"""
什么是迭代器?什么是生成器?两者有什么区别?
协程的实现原理.
asyncio实现原理
用协程实现一个计算平均数的函数
编写一个asyncio异步程序
扩展: 了解aiohttp异步请求网址
"""
# 迭代器可以用来表示一个数据流, 提供了数据的惰性返回功能(只有我们主动去使用next方法调用, 才会返回值).

# 生成器是一种特殊的迭代器, 在迭代器惰性返回数据的基础上, 提供了额外的功能, 实现了程序的暂停.

# 生成器和迭代器的区别:同样提供了惰性返回的功能, 迭代器侧重于提供数据的惰性返回功能, 生成器侧重于指令的惰性返回功能

# 协程的实现原理就是生成器的实现原理, 在生成器的基础上又提供了传递值的功能.

# asyncio实现原理: 自动维护了一个事件队列, 然后循环访问事件来完成异步的消息维护.

"""
利用协成计算平均数
"""

#
# def avg():
#     sum = 0
#     length = 0
#     while True:
#         try:
#             result = yield sum/length
#         except ZeroDivisionError:
#             result = yield 0
#         sum += result
#         length += 1
#
# my_avg = avg()
# print(next(my_avg))
# print(my_avg.send(2))
# print(my_avg.send(3))

import asyncio
import time


class Response:
    staus_code = 200


async def sim_request(index):
    print(f"模拟发送请求 Index: {index}")
    response = Response()
    # 模拟网络延迟
    # 当前是单线程运行的, 如果调用的是time.sleep(1), 那么这个线程会被阻塞
    # 当前线程被阻塞之后, 不会让渡cpu资源, 异步的效率就不会体现
    await asyncio.sleep(1)
    print(f"request index {index}, response status_code: {response.staus_code}")
    return response.staus_code

# 获取消息队列
loop = asyncio.get_event_loop()

# 包装任务
task_array = []
for i in range(100):
    task_array.append(sim_request(i))

# 循环访问事件来完成异步的消息维护
loop.run_until_complete(asyncio.wait(task_array))

# 关闭事件循环
loop.close()